/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.upn.sigemfi.plt.bc;

import edu.upn.sigemfi.plt.be.Cuenta;
import edu.upn.sigemfi.plt.be.DetalleCuentaCliente;
import edu.upn.sigemfi.plt.be.EstadoDetalleCuenta;
import edu.upn.sigemfi.plt.be.TarjetaDebito;
import edu.upn.sigemfi.seg.be.PersonaNatural;
import edu.upn.sigemfi.seg.be.PersonaJuridica;
import edu.upn.sigemfi.seg.be.Persona;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import edu.upn.sigemfi.plt.be.TipoTipoCuenta;
import edu.upn.sigemfi.plt.be.TipoCuenta;

/**
 *
 * @author Administrador
 */
@Stateless
public class CuentaFacade implements CuentaFacadeLocal {

    @PersistenceContext
    private EntityManager em;

    public void create(Cuenta cuenta) {
        em.persist(cuenta);
    }

    public void edit(Cuenta cuenta) {
        em.merge(cuenta);
    }

    public void remove(Cuenta cuenta) {
        em.remove(em.merge(cuenta));
    }

    public Cuenta find(Object id) {
        return em.find(Cuenta.class, id);
    }

    public List<Cuenta> findAll() {
        return em.createQuery("select object(o) from Cuenta as o").getResultList();
    }

    public Cuenta buscarCuentaPorNroCuenta(String nroCuenta) {
        return (Cuenta) em.createQuery("SELECT object(o) FROM Cuenta as o WHERE o.nroCuenta = :nroCuenta").setParameter("nroCuenta", nroCuenta).getSingleResult();
    }
//Utilizado por VFI y CAN

    public List<Cuenta> buscarCuentaPorTarjeta(TarjetaDebito fidPltTarjetaDebito) {
        return em.createQuery("SELECT object(o) FROM Cuenta as o WHERE o.fidPltTarjetaDebito = :fidPltTarjetaDebito ").setParameter("fidPltTarjetaDebito", fidPltTarjetaDebito).getResultList();
    }

    public List<Cuenta> buscarCuentaPorMontoActual(String signo, double montoActual) {
        // em.createQuery("Select object(o) from PersonaNatural o Where o.dniPersona = ?1").setParameter(1, dni).getSingleResult();
        return em.createQuery("SELECT object(o) FROM Cuenta as o WHERE o.montoActual " +
                signo + " ?1").setParameter(1, montoActual).getResultList();
    //return  em.createQuery("SELECT object(o) FROM Cuenta as o WHERE o.montoActual :signo :montoActual").setParameter("montoActual", montoActual).setParameter("signo", signo).getResultList();
    }

//    public List<Cuenta> buscarCuentasPorDni(String dni) {
//        return em.createQuery("SELECT c FROM DetalleCuentaCliente as dcc inner join dcc.persona as p inner join dcc.cuenta as c " +
//                "WHERE p.xtipo = 'PEN' AND " +
//                "p.idPersona = ALL (SELECT pn.idPersona FROM PersonaNatural as pn WHERE pn.dniPersona = :dniPersona )").setParameter("dniPersona", dni).getResultList();
//    }

//    public List<Cuenta> buscarCuentasPorRuc(String ruc) {
//        return em.createQuery("SELECT c FROM DetalleCuentaCliente as dcc inner join dcc.persona as p inner join dcc.cuenta as c " +
//                "WHERE p.xtipo = 'PEJ' AND " +
//                "p.idPersona = ALL (SELECT pj.idPersona FROM PersonaJuridica as pj WHERE pj.ruc = :ruc )").setParameter("ruc", ruc).getResultList();
//    }
    public List<Cuenta> buscarCuentasPorDni(String dni) {
        return em.createQuery("select dc.cuenta from DetalleCuentaCliente as dc WHERE dc.persona.idPersona  IN (SELECT pn.idPersona FROM PersonaNatural as pn WHERE pn.dniPersona = :dni )").setParameter("dni", dni).getResultList();
    }

    

    public List<Cuenta> buscarCuentasPorRuc(String ruc) {
        return em.createQuery("select dc.cuenta from DetalleCuentaCliente as dc WHERE dc.persona.idPersona  IN (SELECT pj.idPersona FROM PersonaJuridica as pj WHERE pj.ruc = :ruc )").setParameter("ruc", ruc).getResultList();
    }

    public List<PersonaNatural> buscarPersonasNaturalesPorNroCuenta(String nroCuenta) {
        //obtengo la lista de personas
        List<Persona> ps = new ArrayList<Persona>();
        DetalleCuentaCliente dcc = new DetalleCuentaCliente();
        dcc.setEstadoDetalleCuentaCliente(EstadoDetalleCuenta.Asociado);
        ps = em.createQuery("SELECT p FROM DetalleCuentaCliente as dcc inner join dcc.persona as p inner join dcc.cuenta as c " +
                "WHERE c.nroCuenta = :nroCuenta AND " +
                "dcc.estadoDetalleCuentaCliente = :estadoDetalle ").setParameter("nroCuenta", nroCuenta).setParameter("estadoDetalle", EstadoDetalleCuenta.Asociado).getResultList();
        //busco a las personas naturales
        List<PersonaNatural> pns = new ArrayList<PersonaNatural>();
        for (Persona p : ps) {
            PersonaNatural pn;
            pn = (PersonaNatural) em.createQuery("SELECT pn FROM PersonaNatural as pn WHERE pn.idPersona = :idPersona ").setParameter("idPersona", p.getIdPersona()).getSingleResult();
            pns.add(pn);
        }

        return pns;
    }

    public List<PersonaJuridica> buscarPersonasJuridicasPorNroCuenta(String nroCuenta) {
        //obtengo la lista de personas
        List<Persona> ps = new ArrayList<Persona>();
        ps = em.createQuery("SELECT p FROM DetalleCuentaCliente as dcc inner join dcc.persona as p inner join dcc.cuenta as c " +
                "WHERE c.nroCuenta = :nroCuenta ").setParameter("nroCuenta", nroCuenta).getResultList();
        //busco a las personas naturales
        List<PersonaJuridica> pjs = new ArrayList<PersonaJuridica>();
        for (Persona p : ps) {
            PersonaJuridica pj;

            pj = (PersonaJuridica) em.createQuery("SELECT pj FROM PersonaJuridica as pj WHERE pj.idPersona = :idPersona ").setParameter("idPersona", p.getIdPersona()).getSingleResult();
            pjs.add(pj);
        }
        return pjs;
    }

    public DetalleCuentaCliente buscarAsociacionPorClienteYCuenta(long idCuenta, long idpersona) {
        DetalleCuentaCliente dcc = new DetalleCuentaCliente();
        dcc = (DetalleCuentaCliente) em.createQuery("SELECT dcc FROM DetalleCuentaCliente as dcc inner join dcc.persona as p inner join dcc.cuenta as c " +
                "WHERE c.idCuenta = :idCuenta AND p.idPersona = :idPersona").setParameter("idCuenta", idCuenta).setParameter("idPersona", idpersona).getSingleResult();
        return dcc;
    }

    public String buscarModalidadAfiliacionPorNumeroCuenta(long idCuenta) {
        List<DetalleCuentaCliente> dccs = new ArrayList<DetalleCuentaCliente>();
        dccs = em.createQuery("SELECT dcc FROM DetalleCuentaCliente as dcc inner join dcc.cuenta as c WHERE c.idCuenta = :idCuenta ").setParameter("idCuenta", idCuenta).getResultList();
        DetalleCuentaCliente dcc = dccs.get(0);
        String modalidad = dcc.getModalidadAfiliacion().toString();
        if (modalidad == "MancomunadoIndistinta") {
            return "Mancomunado Indistinta";
        } else if (modalidad == "MancomunadoIndistinta") {
            return "Mancomunado Conjunta";
        } else {
            return modalidad; //devolvera "Individual"
        }
    }

    public List<Cuenta> buscarCuentasPorTipoCuenta(TipoTipoCuenta tipoTipoCuenta) {
        return em.createQuery("SELECT c FROM Cuenta as c inner join c.fidPltTipoCuenta as tp " +
                "WHERE tp.tipoTipoCuenta = :tipoCuenta").setParameter("tipoCuenta", tipoTipoCuenta).getResultList();
    }

    public List<Cuenta> buscarCuentasPorTipoCuenta(TipoCuenta tipoCuenta) {
        return em.createQuery("SELECT c FROM Cuenta as c WHERE c.fidPltTipoCuenta = :tipoCuenta").setParameter("tipoCuenta", tipoCuenta).getResultList();
    }

    public List<TipoCuenta> buscarTipoCuentaPorTipoTipoCuenta(TipoTipoCuenta tipoTipoCuenta) {
        return em.createQuery("SELECT tp FROM TipoCuenta as tp WHERE tp.tipoTipoCuenta = :tipoCuenta").setParameter("tipoCuenta", tipoTipoCuenta).getResultList();
    }

}
